package com.jiangds.open.check.processor;

import com.jiangds.open.annotation.CheckRule;
import com.jiangds.open.check.Checker;
import com.jiangds.open.util.TimeUtil;
import java.time.LocalDateTime;
import java.util.List;
import java.util.function.Function;

/**
 * {@link SingleProcessor} 单项校验流程器
 *
 * @author jiangliang
 * @since 2021/1/6 15:24
 */
public interface SingleProcessor {

    /**
     * 注解校验
     * @param type 目标类型
     * @param target 目标值
     * @param checkRules 规则列表
     */
     void  annotationCheck(Class<?> type, Object target, List<CheckRule> checkRules);

    /**
     * 流程方法 见 {@link ProcessorType}
     * @param checker  校验器
     * @param checkRule 校验规则
     * @param coverNumber 范围数字转换器
     * @param convertDate 范围日器装换器
     * @param processorType 流程类型
     * @param <R> 范围类型
     * @param <T> 目标类型
     */
    default <R extends Number, T> void processorCheck(
            Checker<R, T> checker,
            CheckRule checkRule,
            Function<Double,R> coverNumber,
            Function<LocalDateTime,T> convertDate,
            ProcessorType processorType) {
        String msg = checkRule.msg();
        //非空校验,所有规则都需要
        if (checkRule.notEmpty()) {
            checker.notEmpty().check(msg);
        }
        //范围校验,所有规则都需要
        if(checkRule.min() != Integer.MIN_VALUE || checkRule.max() != Integer.MAX_VALUE){
            checker.range(coverNumber.apply(checkRule.min()),coverNumber.apply(checkRule.max())).check(msg);
        }
        //根据不同的规则类型,选择要校验的项目
        switch (processorType) {
            //字符串 或者 数字 存在正则校验
            case STRING_OR_NUMBER: {
                if (!"".equals(checkRule.regex())) {
                    checker.regex(checkRule.regex()).check(msg);
                }
                break;
            }
            //日期 存在时间范围的校验
            case DATE: {
                if(!"".equals(checkRule.before())){
                    LocalDateTime before = TimeUtil.parseString(checkRule.before(),checkRule.dateFormat());
                    checker.less(convertDate.apply(before)).check(msg);;
                }
                if(!"".equals(checkRule.after())){
                    LocalDateTime after = TimeUtil.parseString(checkRule.after(),checkRule.dateFormat());
                    checker.greater(convertDate.apply(after)).check(msg);;
                }
                break;
            }
            default:
        }
    }



}

